CloudFormation Hooksで強い権限のIoTポリシーの作成をブロックしてみた

CloudFormation Hooksで強い権限のIoTポリシーの作成をブロックしてみた

CloudFormation Hooksのお試しとしてIoTポリシーで強い権限を作成するCloudFormationをブロックしてみました。
Clock Icon2024.12.15

はじめに

製造ビジネステクノロジー部の佐藤智樹です。
本ブログは「クラスメソッド発 製造業 Advent Calendar 2024」14日目の記事です。

今回は先日発表されたCloudFormation Hookのカスタムフックを使ってIoTポリシーで権限の強いポリシーが作成された場合にブロックする実装を試してみます。IoTポリシーはデバイスにAWSアカウントへの操作権限を与えるものです。デバイスが乗っ取られた場合、デバイスのバックエンドであるAWS側全体に影響が及ぶ可能性があります。これを防ぐためにCloudFormation Hookを試してみます。

IoTポリシー以外にも、CloudFormation Hookを使う際の参考にしてみてください。

参考

https://aws.amazon.com/jp/blogs/devops/introducing-a-managed-hook-for-guard/

やってみた

今回は、CloudFormation Hookを使ってIoTポリシーの作成を制限する実装を試します。Hookの言語として今回はGuard Domain Specific Language(以降Guard DSL)を使います。手順としてはS3バケットへ先にGuard DSLで記述したファイルを配置し、Hookで先程のファイルを設定、最終的にIoTポリシーの作成を試してみます。

S3バケットにGuard DSLを登録

まずはIoTポリシーに対するGuard DSLを記述します。今回は以下で提供されているリファレンスをベースに記述します。

https://github.com/aws-cloudformation/aws-guard-rules-registry/tree/main

IoTポリシーに関する設定は以下にあるのでこちらをベースに、ポリシーのアクションへのワイルドカード利用を制限するように記述します。

https://github.com/aws-cloudformation/aws-guard-rules-registry/blob/main/rules/aws/amazon_iot/iot_policy_wildcard_action_rule.guard

NAGなどは利用していないため、iot_policy_wildcard_action_ruleに設定する条件(33~36行目)は省いて記述します。

let iot_policy_wildcard_action_rule = Resources.*[Type == 'AWS::IoT::Policy']

rule IOT_POLICY_WILDCARD_ACTION_RULE when %iot_policy_wildcard_action_rule !empty {
  let violations = %iot_policy_wildcard_action_rule[
    some Properties.PolicyDocument.Statement[*] {
      some Action[*] in ["*", /^[a-zA-Z0-9]*:\*$/]
      Effect == "Allow"
    }
  ]
  %violations empty
  <<
    Violation: IoT policy should not allow * action.
    Fix: Specify explicit actions in the IoT Policy.
  >>
}

このGuardルールを適当なS3バケット上に保存します。これでルールの準備は完了です。

CloudFormation Hookを設定する

次は、画面コンソールからCloudFormation Hookを設定していきます。CloudFormationの画面からHooksから「フックを作成」を選択します。

スクリーンショット 2024-12-14 17.30.10.png

以下の画面で先程登録したS3上のルールを選択して設定します。今回は簡略化のため、Guard出力レポートのS3バケットは同じバケットに設定します。

スクリーンショット 2024-12-14 16.25.17.png

次の画面で、フック名を設定します。フック名はアカウントとリージョン内で一意で、ルールに従うように設定します。今回はPrivate::Guard::IotHookとします。フックを適用する単位であるフックのターゲットは今回はスタックとCloud Control APIに設定します。アクションは作成だけに設定してフックのモードは、引っかかったときにリソース作成をさせないため失敗に設定します。実行ロールはNew execution roleを設定して、適当な名前でロールを作成します。

スクリーンショット 2024-12-14 16.25.47.png

フックのフィルターを選択します。今回はどんなリソースにも判定する必要はないのでAWS::IoT::Policyだけを対象として、スタックやスタックロールなどはすべてを対象にします。

スクリーンショット 2024-12-14 16.27.50.png

最後確認画面が出るので、フックをアクティブにするをクリックすれば完了です。

IoTポリシーを作成してみる

設定が整ったので、IoTポリシーを作成してみます。今回はCloudFormationからポリシーを作成してみます。以下のテンプレートを利用します。

AWSTemplateFormatVersion: "2010-09-09"
Description: This template creates a admin iot policy

Resources:
      SampleIotPolicy:
        Type: AWS::IoT::Policy
        Properties:
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - "*"
                Resource:
                  - "*"
          PolicyName: SampleIotPolicy 

認証情報を設定してCLIから実行してみます。

% aws cloudformation create-stack --stack-name my-iot-policy-stack --template-body file://iot_policy.yml

{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/my-iot-policy-stack/xxxxxxx-ba28-11ef-a76e-xxxxxxxxxxxx"
}

CloudFormationの結果を確認すると、エラーになっていることがわかります。エラー原因はこの画面の下部に書かれているS3の出力先に詳細が記載されます。

スクリーンショット 2024-12-14 23.46.19.png

ファイルの中身を抜粋。Guardに書いた内容で実行者側にエラーになった理由を伝えられます。

...
"messages": {
  "custom_message": "\n    Violation: IoT policy should not allow * action.\n    Fix: Specify explicit actions in the IoT Policy.\n  ",
}
...

今回はCloud Control APIの方は試せなかったのでまた別途試して追加してみます。

所感

HooksがCloudFormationだけでなく、Cloud Control APIにも対応したのでガバナンスをかける領域が広がり、将来的には画面コンソールにも制限をかけれると権限が強い設定をあらかじめ防ぐことが出来良さそうです。特にIoTの場合、認証情報が手元以外のデバイスに出ていくため特に重要な制限にもなるかと思います。気になった方は是非使ってみてください!

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.